package controllers

import (
	"errors"
	"github.com/goravel/framework/contracts/http"
	"github.com/goravel/framework/database/orm"
	"github.com/goravel/framework/facades"
	"github.com/goravel/framework/support/carbon"
	"github.com/spf13/cast"
	"goravel/app/models"
)

type DashboardController struct {
	//Dependent services
}

func NewDashboardController() *DashboardController {
	return &DashboardController{
		//Inject services
	}
}

func (r *DashboardController) Index(ctx http.Context) http.Response {
	var downloadRecordCount int64
	facades.Orm().Query().Table("downloadrecords").Count(&downloadRecordCount)
	var userCount int64
	facades.Orm().Query().Table("users").Count(&userCount)
	var configurationCount int64
	facades.Orm().Query().Table("configurations").Count(&configurationCount)
	var orderCount int64
	facades.Orm().Query().Table("orders").Count(&orderCount)
	//10种日志的总数
	var adminlogCount int64
	facades.Orm().Query().Table("adminlogs").Count(&adminlogCount)
	var chatlogCount int64
	facades.Orm().Query().Table("chatlogs").Count(&chatlogCount)
	var killlockCount int64
	facades.Orm().Query().Table("killlogs").Count(&killlockCount)
	var loginlogCount int64
	facades.Orm().Query().Table("loginlogs").Count(&loginlogCount)
	var violationlogCount int64
	facades.Orm().Query().Table("violationlogs").Count(&violationlogCount)
	var minelogCount int64
	facades.Orm().Query().Table("minelogs").Count(&minelogCount)
	var landflaglogCount int64
	facades.Orm().Query().Table("landflags").Count(&landflaglogCount)
	var prylocklogCount int64
	facades.Orm().Query().Table("prylocklogs").Count(&prylocklogCount)
	var tradelogCount int64
	facades.Orm().Query().Table("tradelogs").Count(&tradelogCount)
	var loginlogsCount int64
	facades.Orm().Query().Table("loginlogs").Count(&loginlogsCount)
	var totalLogCount = adminlogCount + chatlogCount + killlockCount + loginlogCount + violationlogCount + minelogCount + landflaglogCount + prylocklogCount + tradelogCount + loginlogsCount

	//未过期用人数
	var overdueUserCount int64
	facades.Orm().Query().Table("users").Where("expire_time > now()").Count(&overdueUserCount)

	return ctx.Response().Json(http.StatusOK, http.Json{
		"data": map[string]interface{}{
			"downloadRecordCount": downloadRecordCount,
			"userCount":           userCount,
			"orderCount":          orderCount,
			"configurationCount":  configurationCount,
			"totalLogCount":       totalLogCount,
			"overdueUserCount":    overdueUserCount,
		},
	})
}

// 统计玩家
func (r *DashboardController) StatisticsPlayer(ctx http.Context) http.Response {
	//	1、从聊天日志中提取所有玩家数据，并添加到gatherplayers表中
	configuration_id := ctx.Request().Header("Configuration_id", "")
	//models.LoginLog{}中查询steam_id，并去重
	loginLogs := []models.LoginLog{}

	facades.Orm().Query().Select("SELECT l1.*\nFROM loginlogs l1" +
		"\nLEFT JOIN loginlogs l2" +
		"\nON (l1.stream_id = l2.stream_id AND l1.action_time < l2.action_time)" +
		"\nWHERE l2.stream_id IS NULL AND l1.login_type = 'in';").Scan(&loginLogs)

	for _, loginLog := range loginLogs {
		var gatherplayer models.Gatherplayer
		facades.Orm().Query().Model(&models.Gatherplayer{}).Where("steam_id=?", loginLog.StreamId).FirstOrCreate(&gatherplayer, models.Gatherplayer{
			SteamId: loginLog.StreamId,
		}, models.Gatherplayer{
			SteamId:         loginLog.StreamId,
			RegisteredAt:    loginLog.ActionTime,
			ConfigurationID: cast.ToUint(configuration_id),
		})
	}
	//	2、今天上线的总玩家数量
	var onlineTotal int64
	facades.Orm().Query().Model(&models.LoginLog{}).Where("login_type=?", "in").
		Distinct("stream_id").
		Where("created_at>?", carbon.Date{carbon.Now()}.StartOfDay()).
		//时间为当天当天的0点到现在
		Count(&onlineTotal)
	//	3、今天上线的新玩家数
	var onlineNew int64
	facades.Orm().Query().Model(&models.LoginLog{}).Where("login_type=?", "in").
		Distinct("stream_id").
		Where("created_at>?", carbon.Date{carbon.Now()}).
		Where("stream_id not in (?)", facades.Orm().Query().Model(&models.Gatherplayer{}).Select("steam_id").
			Count(&onlineNew))
	//	4、玩家总数
	var playerTotal int64
	facades.Orm().Query().Model(&models.Gatherplayer{}).
		Where("configuration_id", cast.ToInt(configuration_id)).Count(&playerTotal)

	//	5、playerstatistics表中的数据
	var playerStatistic models.Playerstatistic
	err := facades.Orm().Query().Model(&models.Playerstatistic{}).
		Where("configuration_id=?", configuration_id).
		Where("date_at=?", carbon.Date{carbon.Now()}.ToDateString()).
		FirstOrFail(&playerStatistic)
	if errors.Is(err, orm.ErrRecordNotFound) {
		//如果没有数据，就创建
		facades.Orm().Query().Create(&models.Playerstatistic{
			ConfigurationID: cast.ToUint(configuration_id),
			OnlineTotal:     cast.ToInt(onlineTotal),
			OnlineNewTotal:  cast.ToInt(onlineNew),
			PlayerCount:     cast.ToInt(playerTotal),
			DateAt:          carbon.Date{carbon.Now()},
		})
	} else {
		//如果有数据，就更新
		facades.Orm().Query().Model(&models.Playerstatistic{}).
			Where("configuration_id=?", configuration_id).
			Where("date_at=?", carbon.Date{carbon.Now()}.ToDateString()).
			Update(&models.Playerstatistic{
				OnlineTotal:    cast.ToInt(onlineTotal),
				OnlineNewTotal: cast.ToInt(onlineNew),
				PlayerCount:    cast.ToInt(playerTotal),
			})
	}
	var playerStatistics []models.Playerstatistic
	facades.Orm().Query().Model(&models.Playerstatistic{}).Where("configuration_id=?", configuration_id).
		Where("date_at>?", carbon.Date{carbon.Now()}.SubDays(7).ToDateString()).
		Find(&playerStatistics)
	return ctx.Response().Json(http.StatusOK, http.Json{
		"message": "统计成功",
		"data": map[string]interface{}{
			"playerStatistic": playerStatistics,
		},
	})
}
